package com.jiuli.liping.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.jiuli.liping.dao.HrDao;
import com.jiuli.liping.dao.ProductOrderDao;
import com.jiuli.liping.dao.UserlistDao;
import com.jiuli.liping.service.HrService;
import com.jiuli.liping.util.MSWordTool;
import com.jiuli.liping.util.POIWordUtil;
import com.jiuli.liping.util.WeiXinUtils;
import com.jiuli.liping.vo.*;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Node;

import javax.xml.crypto.Data;

@Service
public class HrServiceImpl implements HrService {
    private ChannelSftp channelSftp;
    private Session session = null;
    private int timeout = 60000;
    @Autowired
    private UserlistDao userlistDao;
    @Autowired
    private ProductOrderDao productOrderDao;
    @Autowired
    private HrDao hrDao;
    public static String access_token = null;
    public static Date access_token_date = null;

    /**
     * 从微信获得access_token
     *
     * @return
     */
    public String getToken() {
        String token = "";
        //1、判断access_token是否存在，不存在的话直接申请
        //2、判断时间是否过期，过期(>=7200秒)申请，否则不用请求直接返回以后的token
        if (null == access_token || "".equals(access_token) || (new Date().getTime() - access_token_date.getTime()) >= (4000 * 1000)) {
            try {
                String urls = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwef2fadef61221778&corpsecret=4hRqvR3e0zY3Lgn5OtbfFKlYbBKDRpuz-qwx1X7DJ_c";

                JSONObject jsonss = WeiXinUtils.getWeiXinApi(urls);

                //设置全局变量
                access_token = jsonss.toString();
                access_token_date = new Date();

                token = jsonss.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            token = access_token;
        }
        return token;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendWechat(HrDto hrDto) {
        hrDto.setFileName(hrDto.getFileName().split("\\.")[0]);
        //String filePath =  "E:\\test";
        String filePath = "C:\\Program Files\\Apache Software Foundation\\Tomcat 9.0_Tomcat9.31\\webapps\\lipingimg";
        SshConfiguration conf = new SshConfiguration();
        conf.setHost("192.168.5.20");
        conf.setUsername("root");
        conf.setPassword("/e7w6r6l0\\");
        conf.setPort(22);
        ZipFile zip = null;
        JSch jSch = new JSch(); //创建JSch对象
        try {
            //从oa下载附件
            session = jSch.getSession(conf.getUsername(), conf.getHost(), conf.getPort());//根据用户名，主机ip和端口获取一个Session对象
            session.setPassword(conf.getPassword()); //设置密码
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);//为Session对象设置properties
            session.setTimeout(timeout);//设置超时
            session.connect();//通过Session建立连接
            channelSftp = (ChannelSftp) session.openChannel("sftp");
            channelSftp.connect();
            channelSftp.get(hrDto.getFileUrl(), filePath);
            channelSftp.quit();
            session.disconnect();

            //将oa的zip附件解压
            String[] split = hrDto.getFileUrl().split("/");
            String zipPath = filePath + "\\" + split[split.length - 1];//压缩包路径
            File file1 = new File(zipPath);//当前压缩文件
            zip = new ZipFile(file1, Charset.forName("gbk"));//防止中文目录，乱码
            String outPath = "";//解压输出路径
            for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zip.getInputStream(entry);
                //指定解压后的文件夹+当前zip文件的名称
                outPath = (filePath + "\\" + zipEntryName).replace("/", File.separator);
                //判断路径是否存在,不存在则创建文件路径
                File file = new File(outPath.substring(0, outPath.lastIndexOf(File.separator)));
                if (!file.exists()) {
                    file.mkdirs();
                }
                System.out.println("当前zip解压之后的路径为：" + outPath);
                OutputStream out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[2048];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
                in.close();
                out.close();
            }
            zip.close();

            //将解压出来的文件复制并重命名
            File oldfile = new File(outPath);
            // File pdfFile = new File(filePath+"\\"+hrDto.getFileName()+".pdf");

//            ActiveXComponent app = null;
//            Dispatch doc = null;
            String openPath = outPath;
            // 要保存的文件的路径


            File newfile1 = new File(filePath + "\\" + hrDto.getFileName() + ".docx");
            if (newfile1.exists() && newfile1.isFile()) {
                //文件存在,先把老的删了再复制新的
                if (newfile1.delete()) {
                    //删除成功  再去复制
                    System.out.println("删除旧文件并生成新文件");
                    Files.copy(oldfile.toPath(), newfile1.toPath());
                }
            } else {
                //文件不存在  直接复制
                Files.copy(oldfile.toPath(), newfile1.toPath());
            }
            String toFileName = filePath + "\\" + hrDto.getFileName() + ".pdf";

            FileInputStream fileInputStream = null;
            FileOutputStream  fileOutputStream=null;
            try {
                // 读取docx文件
                fileInputStream = new FileInputStream(filePath + "\\" + hrDto.getFileName() + ".docx");
                XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream);
                PdfOptions pdfOptions = PdfOptions.create();
                // 输出路径
                fileOutputStream = new FileOutputStream(toFileName);
                // 调用转换
                PdfConverter.getInstance().convert(xwpfDocument,fileOutputStream,pdfOptions);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                fileInputStream.close();
                fileOutputStream.close();
            }
            Files.delete(newfile1.toPath());
            for (HrVo hrVo : hrDto.getHrVos()) {
                File newfile = new File(filePath + "\\" + hrDto.getFileName() + "-" + hrVo.getName() + "-" + hrVo.getCode() + ".docx");
                if (newfile.exists() && newfile.isFile()) {
                    //文件存在,先把老的删了再复制新的
                    if (newfile.delete()) {
                        //删除成功  再去复制
                        System.out.println("删除旧文件并生成新文件");
                        Files.copy(oldfile.toPath(), newfile.toPath());
                    }
                } else {
                    //文件不存在  直接复制
                    Files.copy(oldfile.toPath(), newfile.toPath());
                }
                hrVo.setFileName(hrDto.getFileName() + ".pdf");
                hrVo.setFileUrl(filePath + "\\" + hrDto.getFileName() + "-" + hrVo.getName() + "-" + hrVo.getCode() + ".docx");
                hrVo.setStatus("0");
                hrDao.save(hrVo);
            }

            File file = new File(zipPath);
            // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
            if (file.exists() && file.isFile()) {
                if (file.delete()) {
                    System.out.println("删除zip文件" + zipPath + "成功！");
                }
            }
            File unfile = new File(outPath);
            // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
            if (unfile.exists() && unfile.isFile()) {
                if (unfile.delete()) {
                    System.out.println("删除解压文件" + outPath + "成功！");
                }
            }
        } catch (JSchException | SftpException | IOException e) {
            e.printStackTrace();
        }
        //微信推送给指定人员
        String token = getToken();
        JSONObject json = JSONObject.parseObject(token);
        AccessToken accessToken = new AccessToken();
        accessToken.setAccess_token(json.getString("access_token"));
        //获得token    json串结束
        String urls = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken.getAccess_token();

        for (HrVo hrVo : hrDto.getHrVos()) {
            Integer wecharId = userlistDao.getWecharIdWx(String.format("%05d", Integer.valueOf(hrVo.getCode())));
            String param = "{" +
                    "\"touser\" :\"" + wecharId + "\" ," +
                    "\"msgtype\" : \"textcard\", " +
                    "\"agentid\" : 1000029, " +
                    "\"textcard\" : {\n" +
                    "            \"title\" : \"岗位说明书签署\",\n" +
                    "            \"description\" : \"<div class=\\\"normal\\\">您好！收到来自人力资源部发起的一份《岗位说明书》电子文件，请点击签署，感谢您的配合！</div>\",\n" +
                    "            \"url\" : \"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wwef2fadef61221778&redirect_uri=http://api.jiuli.com:8070/documentSign&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect\",\n" +
                    "            \"btntxt\":\"更多\"\n" +
                    "   }," +
                    "\"safe\" : 0, " +
                    "\"enable_id_trans\" : 0, " +
                    "\"enable_duplicate_check\" : 0, " +
                    "}";
            String json1 = WeiXinUtils.getWeiXinApiPost(urls, param);
            System.out.println("推送返回:" + json1);
        }

    }




    @Override
    public List<HrVo> getList(String userCode) {

        return hrDao.getList(userCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnMsg test(String id) {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String formatStr = formatter.format(new Date());

        ReturnMsg returnMsg = new ReturnMsg();
        HrVo detail = hrDao.getDetail(id);



        if (detail == null) {
            returnMsg.setMessage("该岗位说明书已签署");
            returnMsg.setFlag(false);
            return returnMsg;
        }
        String lider = hrDao.getLider(detail.getCode());
        String openPath = detail.getFileUrl();
        // 要保存的文件的路径
        int one = detail.getFileUrl().lastIndexOf(".");
        String substring = detail.getFileUrl().substring(0,one);
        String toFileName = substring + ".pdf";
        String toFileNameDocx = substring + ".docx";
        FileInputStream fileInputStream = null;
        FileOutputStream  fileOutputStream =null;
        try {
            //读文件
            fileInputStream = new FileInputStream(openPath);
            System.out.println("打开路径:" + openPath);
            XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream);
            //文本数据
            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("name", detail.getName());
            contentMap.put("date", formatStr);
            contentMap.put("superior", lider);
            contentMap.put("approvalDate", formatStr);
            //替换内容
            POIWordUtil.replaceWord(xwpfDocument,contentMap);


           // 输出路径
            fileOutputStream = new FileOutputStream(toFileNameDocx);
            xwpfDocument.write(fileOutputStream);

            ActiveXComponent app = null;
            Dispatch doc = null;

            Dispatch docs = null;
            if (app == null || app.m_pDispatch == 0) {
                app = new ActiveXComponent("Word.Application");
                app.setProperty("Visible", new Variant(false));
                app.setProperty("DisplayAlerts", new Variant(false));
            }
            if (docs == null) {
                // 获得documents对象
                docs = app.getProperty("Documents").toDispatch();
            }
            doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[]{toFileNameDocx, new Variant(false), new Variant(true)}, new int[1])
                    .toDispatch();
            Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[]{toFileName, new Variant(17)}, new int[1]);
            Dispatch.call((Dispatch) doc, "Close", new Variant(false));
            app.invoke("Quit", new Variant[0]);
            System.out.println("关闭文档");
            ComThread.Release();


            System.out.println("输出路径:" + toFileName);

            System.out.println("转换成功" );
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
                System.out.println("关闭转换流" );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }



        File unfile = new File(openPath);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (unfile.exists() && unfile.isFile()) {
            if (unfile.delete()) {
                System.out.println("删除解压文件" + openPath + "成功！");
            }
        }
        //更新岗位表状态
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        hrDao.updateStatus(id, dateFormat.format(date));
        //ComThread.Release();
        returnMsg.setMessage("签署成功");
        returnMsg.setFlag(true);
        return returnMsg;
    }

    @Override
    public ReturnMsg delete(String workCode) {
        if (workCode.equals("S")) {
            workCode = workCode;
        } else {
            if (workCode.substring(0, 1).equals("0")) {
                workCode = workCode.substring(1, workCode.length());
            }
        }
        ReturnMsg returnMsg = new ReturnMsg();
        returnMsg.setFlag(true);
        returnMsg.setMessage("离职成功");
        productOrderDao.deleteByCode(workCode);
        return returnMsg;
    }


}
